#include <iostream>
#include <cstdio>
#include <cstdarg>
#include <csignal>
#include <cstdlib>
#include <fcntl.h>
#include "../es.h"
#include "../es_log.h"
#include "../es_util.h"
#include "../es_socket.h"
#include "../extra/es_lua_http_handler.h"

#ifndef O_NONBLOCK
#define	O_NONBLOCK 1
#endif

using namespace std;


class TestLogger : public esvr::Logger
{
public:
	virtual void log(esvr::LogLevel level, const char* fmt, ...) override final
	{
		va_list args;
		printf("%s [%s]--[t-%lld] ", esvr::get_current_datetime_str().c_str(), esvr::LogLevelStr[level], std::this_thread::get_id());
		va_start(args, fmt);
		vfprintf(stdout, fmt, args);
		va_end(args);
		printf("\n");
	}
};

esvr::Logger* esvr::g_LoggerInst =	new TestLogger;

static socket_t get_server_fd()
{
	static socket_t server_fd = esvr::es_init_svr(NULL, 2048);
	return server_fd;
}

void close_server_fd()
{
	//println("close socket");
	esvr::IOManager::instance().stop();
	esvr::es_close(get_server_fd());
	esvr::es_destroy_sock_module();
	if (esvr::g_LoggerInst)
	{
		delete esvr::g_LoggerInst;
		esvr::g_LoggerInst = NULL;
	}
}

void signal_func(int signal)
{
	if(signal == SIGINT)
	{
		close_server_fd();
		exit(0);
	}
}


int main()
{
	::atexit(close_server_fd);
	signal(SIGINT, signal_func);
	esvr::es_init_sock_module();
	socket_t server_fd = get_server_fd();
	int len = 1;
	esvr::es_setopt(server_fd, SO_REUSEADDR, (void*) &len , sizeof(len));
	esvr::es_fcntl(server_fd, O_NONBLOCK, true);
	//println("Hello, World!");
	esvr::es_listen(server_fd);
	esvr::LuaHttpHandler ev;
	esvr::EventBus& bus = esvr::EventBus::get_instance();
	bus.add_handler<esvr::ConnectedEvent>(&ev);
	bus.add_handler<esvr::ClosedEvent>(&ev);
	bus.add_handler<esvr::ReadEvent>(&ev);
	bus.add_handler<esvr::WriteEvent>(&ev);
	esvr::IOManager::instance().start(server_fd);
	return 0;
}
